#include <baker/Vector.h>
#include <unittest++/UnitTest++.h>

using namespace baker;

SUITE( TestVec2 )
{
    TEST( sizeof )
    {
        CHECK_EQUAL( sizeof( Vec2 ), sizeof( float ) * 2 );
    }

    TEST( cstor )
    {
        const Vec2 vec( 123.456, 234.567 );

        CHECK_CLOSE( vec.x(), 123.456, EPSILON );
        CHECK_CLOSE( vec.y(), 234.567, EPSILON );

        CHECK_CLOSE( vec.x(), vec[0], EPSILON );
        CHECK_CLOSE( vec.y(), vec[1], EPSILON );

        Vec2 vec2;
        vec2.x( 345.678 ).y( 456.789 );

        CHECK_CLOSE( vec2.x(), 345.678, EPSILON );
        CHECK_CLOSE( vec2.y(), 456.789, EPSILON );
    }

    TEST( equal )
    {
        const Vec2 vec1( 123.456, 234.567 );
        const Vec2 vec2( 123.456, 234.567 );

        CHECK( vec1 == vec2 );
    }

    TEST( add )
    {
        const Vec2 vec1( 0, 1 );
        const Vec2 vec2( 1, 2 );

        Vec2 result;

        result = vec1 + vec2;

        CHECK_CLOSE( result.x(), 1.0, EPSILON );
        CHECK_CLOSE( result.y(), 3.0, EPSILON );

        result = vec1 - vec2;

        CHECK_CLOSE( result.x(), -1.0, EPSILON );
        CHECK_CLOSE( result.y(), -1.0, EPSILON );
    }

    TEST( mul )
    {
        const Vec2 vec1( 1, 2 );
        const Vec2 vec2( 2, 3 );

        Vec2 result;

        result = vec1 * vec2;

        CHECK_CLOSE( result.x(), 2.0, EPSILON );
        CHECK_CLOSE( result.y(), 6.0, EPSILON );

        result = vec1 * 3;

        CHECK_CLOSE( result.x(), 3.0, EPSILON );
        CHECK_CLOSE( result.y(), 6.0, EPSILON );

        result = 3 * vec2;

        CHECK_CLOSE( result.x(), 6.0, EPSILON );
        CHECK_CLOSE( result.y(), 9.0, EPSILON );
    }

    TEST( dot )
    {
        const Vec2 vec1( 0, 1 );
        const Vec2 vec2( 1, 0 );

        CHECK_CLOSE( dot( vec1, vec2 ), 0.0, EPSILON );

        const Vec2 vec3( 1, 1 );
        const Vec2 vec4( 1, 1 );

        CHECK_CLOSE( dot( vec3, vec4 ), 2.0, EPSILON );
    }

    TEST( normalize )
    {
        const Vec2 vec( 123.456, 234.567 );

        CHECK_CLOSE( length( normalizedCopy( vec ) ), 1.0, EPSILON );
    }

    TEST( negative )
    {
        const Vec2 vec( 123.456, 234.567 );

        CHECK_CLOSE( ( -vec ).x(), -123.456, EPSILON );
        CHECK_CLOSE( ( -vec ).y(), -234.567, EPSILON );
    }

}

SUITE( TestVec3 )
{
    TEST( sizeof )
    {
        CHECK_EQUAL( sizeof( Vec3 ), sizeof( float ) * 3 );
    }

    TEST( cross )
    {
        const Vec3 i( 1, 0, 0 );
        const Vec3 j( 0, 1, 0 );
        const Vec3 k( 0, 0, 1 );

        CHECK( cross( i, j ) == k );

        CHECK( cross( j, k ) == i );

        CHECK( cross( k, i ) == j );

        CHECK( cross( Vec3( 1, 2, 3 ), Vec3( 4, 5, 6 ) ) == Vec3( -3, 6, -3 ) );

    }
}
